import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

/*ReactDOM.render(<App />, document.getElementById('root'));*/

/*import dva, {connect} from 'dva';
import key from 'keymaster'; //按键监听

function request(url, options) { //fetch的简单封装
    return fetch(url, options)
        .then((response) => {
            if (response.status >= 200 && response.status < 300) {
                return response;
            }

            const error = new Error(response.statusText);
            error.response = response;
            throw error;
        })
        .then((response) => {
            return response.json();
        })
        .then((data) => {
            return data;
        })
        .catch((err) => {
            return err;
        });
}

const app = dva(); //创建应用

// 简单理解，model，代表“数据库服务器”，用来管理“数据库实例”。namespace，代表“当前数据库实例的名称”。state，用于初始化“当前数据库实例的数据结构”。reducers，定义了“可用来改变当前数据库实例的数据结构及数据的接口”
app.model({
    namespace: 'ns', //“ns”，是“命名空间的关键字”，是“当前model的名称”，更是“当前数据库实例的名称”
    state: 100, //初始化“当前数据库实例的数据结构”，可以是基础数据类型（整型，字符串等），也可以是数组、对象。附：关于state，详情见react
    subscriptions: { //事件监听。从“源”获取数据
        setup({ dispatch, history }) {
            console.log("setup");
        },
        keyEvent({dispatch}) {
            key('⌘+up, ctrl+up', () => {
                console.log("keyEvent");
            });
        },
    },
    effects: { //异步数据流处理，而后将结果转交给reducers进行处理（redux-saga）
        *random_request(action, { call, put }) {
            const response = yield call(request, 'http://localhost/react/random'); //暂停，以阻塞方式调用函数，直到取到数据
            yield put({type: "random", payload: response}); //向reducers发送消息
        },
        *reset_request(action, { call, put }) {
            const response = yield call(request, 'http://localhost/react/reset', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({num: 100})
            });
            yield put({type: "reset", payload: response}); //向reducers发送消息
        },
    },
    reducers: { //同步数据流处理，定义了“可用来改变当前数据库实例的数据结构及数据的接口”（redux）
        add  (state) {
            console.log("+");
            console.log(state);
            return state+1;
        },
        minus(state) {
            console.log("-");
            console.log(state);
            return state-1;
        },
        random(state, action) {
            console.log("random");
            console.log(state);
            console.log(action);
            return action.payload;
        },
        reset(state, action) {
            console.log("reset");
            console.log(state);
            console.log(action);
            return action.payload;
        },
    },
});

class Component extends React.Component { //视图，react
    handleAdd = () => { //自定义事件处理方法，响应onClick事件
        this.props.dispatch({type:"ns/add"}); //发送指定事件。事件类型type，由命名空间ns和行为add组成。简单理解，对ns数据库实例进行add操作
    }

    handleMinus = () => {
        this.props.dispatch({type:"ns/minus"});
    }

    handleRandom = () => {
        this.props.dispatch({type:"ns/random_request"});
    }

    handleReset = () => {
        this.props.dispatch({type:"ns/reset_request"});
    }

    render() {
        return (
            <div className={"container"}>
                <h2>{ this.props.num }</h2>
                <button type="button" name="+" onClick={this.handleAdd}>+</button>
                <button type="button" name="-" onClick={this.handleMinus}>-</button>
                <button type="button" name="random" onClick={this.handleRandom}>random</button>
                <button type="button" name="reset" onClick={this.handleReset}>reset</button>
            </div>
        );
    }
}

const mapStateToProps = (model) => {
    console.log(model);
    return {num: model.ns}; //model.namespace（数据库服务器.数据库实例名称）
}

const TargetComponent = connect(mapStateToProps,)(Component); //mapStateToProps绑定数据，mapDispatchToProps绑定方法（具体实现，略）。简单理解，connect会查下数据库找到所需数据，然后把所需数据绑定到子组件Component的props上

app.router(() => { //匿名函数，返回一个路由组件，即具体页面page
    return <TargetComponent />; //系统首页
});//注册视图

app.start('#root'); //启动应用。相当于，ReactDOM.render(<TargetComponent/>, document.getElementById('root'));*/

//-------------------------------------------------------------------------------------------------------------------------

import dva, {connect} from 'dva';
import key from "keymaster";

function request(url, options) { //fetch的简单封装
    return fetch(url, options)
        .then((response) => {
            if (response.status >= 200 && response.status < 300) {
                return response;
            }

            const error = new Error(response.statusText);
            error.response = response;
            throw error;
        })
        .then((response) => {
            return response.json();
        })
        .then((data) => {
            return data;
        })
        .catch((err) => {
            return err;
        });
}

const app = dva(); //创建应用

// 简单理解，model，代表“数据库服务器”，用来管理“数据库实例”。namespace，代表“当前数据库实例的名称”。state，用于初始化“当前数据库实例的数据结构”。reducers，定义了“可用来改变当前数据库实例的数据结构及数据的接口”
app.model({
    namespace: 'ns', //“ns”，是“命名空间的关键字”，是“当前model的名称”，更是“当前数据库实例的名称”
    state: {num: 100}, //初始化“当前数据库实例的数据结构”，可以是基础数据类型（整型，字符串等），也可以是数组、对象。附：关于state，详情见react
    subscriptions: { //事件监听。从“源”获取数据
        setup({ dispatch, history }) {
            console.log("setup");
        },
        keyEvent({dispatch}) {
            key('⌘+up, ctrl+up', () => {
                console.log("keyEvent");
            });
        },
    },
    effects: { //异步数据流处理，而后将结果转交给reducers进行处理（redux-saga）
        *random_request(action, { call, put }) {
            const response = yield call(request, 'http://localhost/react/random'); //暂停，以阻塞方式调用函数，直到取到数据
            yield put({type: "random", payload: response}); //向reducers发送消息
        },
        *reset_request(action, { call, put }) {
            const response = yield call(request, 'http://localhost/react/reset', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({num: 100})
            });
            yield put({type: "reset", payload: response}); //向reducers发送消息
        },
    },
    reducers: { //同步数据流处理，定义了“可用来改变当前数据库实例的数据结构及数据的接口”（redux）
        add  (state) {
            console.log("+");
            console.log(state);
            return {...state, num: state.num+1};
        },
        minus(state) {
            console.log("-");
            console.log(state);
            return {...state, num: state.num-1};
        },
        random(state, action) {
            console.log("random");
            console.log(state);
            console.log(action);
            return {...state, num: action.payload};
        },
        reset(state, action) {
            console.log("reset");
            console.log(state);
            console.log(action);
            return {...state, num: action.payload};
        },
    },
});

class Component extends React.Component { //视图，react
    handleAdd = () => { //自定义事件处理方法，响应onClick事件
        this.props.dispatch({type:"ns/add"}); //发送指定事件。事件类型type，由命名空间ns和行为add组成。简单理解，对ns数据库实例进行add操作
    }

    handleMinus = () => {
        this.props.dispatch({type:"ns/minus"});
    }

    handleRandom = () => {
        this.props.dispatch({type:"ns/random_request"});
    }

    handleReset = () => {
        this.props.dispatch({type:"ns/reset_request"});
    }

    render() {
        return (
            <div className={"container"}>
                <h2>{ this.props.num }</h2>
                <button type="button" name="+" onClick={this.handleAdd}>+</button>
                <button type="button" name="-" onClick={this.handleMinus}>-</button>
                <button type="button" name="random" onClick={this.handleRandom}>random</button>
                <button type="button" name="reset" onClick={this.handleReset}>reset</button>
            </div>
        );
    }
}

const mapStateToProps = (model) => {
    console.log(model);
    return {num: model.ns.num}; //model.namespace（数据库服务器.数据库实例名称）
}

const TargetComponent = connect(mapStateToProps,)(Component); //mapStateToProps绑定数据，mapDispatchToProps绑定方法（具体实现，略）。简单理解，connect会查下数据库找到所需数据，然后把所需数据绑定到子组件Component的props上

app.router(() => { //匿名函数，返回一个路由组件，即具体页面page
    return <TargetComponent />; //系统首页
});//注册视图

app.start('#root'); //启动应用。相当于，ReactDOM.render(<TargetComponent/>, document.getElementById('root'));

registerServiceWorker();
